package com.example.demofdfs.util.shell;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.UUID;
import java.util.function.Consumer;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.jcraft.jsch.JSchException;

import net.neoremind.sshxcute.core.Result;

@Component
public class CommandPool implements Pool{
	
	Logger log = LoggerFactory.getLogger(getClass());

	@Value("${ansible.host}")
	private String host;
	@Value("${ansible.user}")
	private String user;
	@Value("${ansible.password}")
	private String password;
	
	/**
	 * 连接会话列表
	 */
	private List<ObjectPool<Command>> list; 
	
	private static int min = 10;		// 初始化连接数
	private static int max = 100;		// 最大连接数
	private static long timeOut = 3000;	// 等待时间
	
	
	/**
	 * 使用 sshxcute 执行命令
	 * @throws JSchException 
	 */
	@Override
	public Result exec(String cmd) throws JSchException {
		
		ObjectPool<Command> objectPool = null;
		Result result;
		try {
			while ((objectPool = getCommand()) == null) {
				waitTime(timeOut); // 获取不到连接, 等待 3秒
			}
			log.info("   执行命令...[ " + cmd + " ]");
			log.info("   会话 id 与 使用次数 [ " + objectPool.getId() + " ] [" + objectPool.getCount() + "]");
			result = objectPool.getObject().exec(cmd);
		} finally {
			close(objectPool);
		}
		
		return result;
	}
	
	/**
	 * 获取连接对象
	 * @return
	 */
	private synchronized ObjectPool<Command> getCommand() {
		log.info("  获取  ssh 连接...");
		// 循环队列, 如果 isUse = false 表示当前对象没有被使用可以获取
		for (ListIterator<ObjectPool<Command>> it = list.listIterator(); it.hasNext(); ) {
			if (! list.isEmpty()) {
				ObjectPool<Command> o = it.next();
				if (! o.isUse()) {
					o.setCount(o.getCount() + 1);
					o.setUse(true);
					return o;
				}
			}
		}
		
		return createObject();
	}
	
	/**
	 * 创建一个连接对象
	 * @return
	 */
	private synchronized ObjectPool<Command> createObject() {
		ObjectPool<Command> objectPool = null;
		if (list.size() < max)
		{
			objectPool = this.getInstance();
			list.add(objectPool);
		}
		
		return objectPool;
	}
	
	/**
	 * 释放连接对象
	 * @param pool
	 */
	private boolean close(ObjectPool<Command> pool) {
		if (pool == null)
			return false;
		log.info("  归还  ssh 连接...");
		pool.setUse(false);
		return true;
	}
	
	/**
	 * 初始化连接池, 大小为10
	 * 随着spring 容器初始化执行一次
	 */
	@PostConstruct
	private void init() {
		list = Collections.synchronizedList(new ArrayList<>());
		log.info("   初始化 ssh 连接池...");
		
		Runnable runnable = ()-> {
			for (int i = 0; i < min; i++) {
				list.add(this.getInstance());
			}
//			list.forEach(new Consumer<ObjectPool<Command>>() {
//				@Override
//				public void accept(ObjectPool<Command> p) {
//					new Thread(()->{
//						try {
//							p.getObject().connect();
//						} catch (JSchException e) {
//							e.printStackTrace();
//						}
//					}).start();
//				}
//			});
		};
		new Thread(runnable).start();
	}
	
	/**
	 * 等待
	 * @param time
	 */
	private void waitTime(long time) {
		try {
			log.info("   等待 ssh 连接...");
			Thread.sleep(time);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取连接实例
	 * @return
	 */
	private ObjectPool<Command> getInstance() {
		return new ObjectPool<Command>(
				new SSHExecCommand(host, user, password), getPoolId());
	}
	
	private String getPoolId() {
		return UUID.randomUUID().toString().replace("-", "") + "-" + ObjectPool.poolCount();
	}
	
	/**
	 * 定时器
	 * 清理长时间未使用的 ssh 连接
	 */
	private void task() {
		
		
	}
	
	
}
